﻿using GDM.Hogar.Controles.ControlesPersonalizados.Comun;
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace GDM.Hogar.Controles.ControlesPersonalizados
{
    [ComVisible(false), Designer(typeof(TransparentLabelDesigner)), ClassInterface(ClassInterfaceType.AutoDispatch), DefaultProperty("Text"), DefaultEvent("Click"), ToolboxItem(true), Description("transparent label control")]
    public partial class TransparentLabel : Control
    {
        private Color _borderColor = Color.Black;

        private DashStyle _borderDashStyle = DashStyle.Solid;

        private BorderStyles _borderStyle;

        private int _borderWidth = 1;

        private ContentAlignment _textAlign = ContentAlignment.MiddleCenter;

        public TransparentLabel()
        {
            InitializeComponent();
            //SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            //SetStyle(ControlStyles.ResizeRedraw, true);
            //SetStyle(ControlStyles.Opaque, false);
            //SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
            //PropertyChanged += OnPropertyChanged;
        }

        public TransparentLabel(IContainer container)
        {
            container.Add(this);

            InitializeComponent();

            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.Opaque, false);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
            PropertyChanged += OnPropertyChanged;
        }

        //- This delegate points to methods which return void and take a boolean
        public delegate void MyEventHandler(bool recreateHandler);

        public event MyEventHandler PropertyChanged;

        [Browsable(true), Category("Border"), Description("Gets or sets the specified border color for the style")]
        public Color BorderColor
        {
            get { return _borderColor; }
            set { _borderColor = value; RaiseEvent(); }
        }

        [Browsable(true), Category("Border"), Description("Gets or sets the specified border dash style for the style")]
        public DashStyle BorderDashStyle
        {
            get { return _borderDashStyle; }
            set { _borderDashStyle = value; RaiseEvent(); }
        }

        [Browsable(true), Category("Border"), Description("Gets or sets the specified border style for the style")]
        public BorderStyles BorderStyle
        {
            get { return _borderStyle; }
            set { _borderStyle = value; RaiseEvent(); }
        }

        [Browsable(true), Category("Border"), Description("Gets or sets the specified border width for the style")]
        public int BorderWidth
        {
            get { return _borderWidth; }
            set { _borderWidth = value; RaiseEvent(); }
        }

        [Browsable(true), Category("Text"), Description("Gets or sets the text inside the control")]
        public override string Text
        {
            get { return base.Text.Replace("TransparentLabel", "TransparentLabel"); }
            set { base.Text = value; RaiseEvent(); }
        }

        [Browsable(true), Category("Text"), Description("ets or sets the alignment of text inside the control")]
        public ContentAlignment TextAlign
        {
            get { return _textAlign; }
            set { _textAlign = value; RaiseEvent(); }
        }

        protected override CreateParams CreateParams
        {
            get
            {
                var cp = base.CreateParams;
                cp.ExStyle = cp.ExStyle | 0x20;
                return cp;
            }
        }

        protected void DrawControlBorder(Graphics g, Rectangle clientRect)
        {
            var objPen = new Pen(_borderColor, _borderWidth);

            clientRect.Width = clientRect.Width - 1;
            clientRect.Height = clientRect.Height - 1;

            switch (_borderStyle)
            {
                case BorderStyles.None:
                    return;

                // DO NOTHING
                case BorderStyles.FixedSingle:
                    objPen.DashStyle = DashStyle.Solid;
                    objPen.Width = 1;
                    objPen.Color = Color.Black;
                    break;

                case BorderStyles.Fixed3D:
                    objPen.DashStyle = DashStyle.Solid;
                    objPen.Width = 2;
                    objPen.Color = Color.Gray;
                    g.DrawRectangle(objPen, clientRect.X, clientRect.Y, clientRect.Width - 1, clientRect.Height - 1);
                    break;

                case BorderStyles.ControlStyle:
                    objPen.DashStyle = _borderDashStyle;
                    break;
            }

            g.DrawRectangle(objPen, clientRect);
            objPen.Dispose();
        }

        protected void DrawControlText(Graphics g, Rectangle clientRect)
        {
            Rectangle textRect = GetTextRectangle(Text, Font, g, clientRect, TextAlign);
            g.DrawString(Text, Font, new SolidBrush(ForeColor), textRect);
        }

        protected Rectangle GetTextRectangle(string text, Font font, Graphics g, Rectangle clientRect, ContentAlignment txtAlign)
        {
            var textSize = g.MeasureString(text, font);
            int textLeft;
            textSize.Width = textSize.Width + 4;
            switch (txtAlign)
            {
                case ContentAlignment.TopLeft:
                    return clientRect;

                case ContentAlignment.TopCenter:
                    textLeft = (clientRect.Width / 2) - (Convert.ToInt32(Math.Truncate(textSize.Width)) / 2);
                    return new Rectangle((clientRect.Left + textLeft), clientRect.Top, Convert.ToInt32(Math.Truncate(textSize.Width)), Convert.ToInt32(Math.Truncate(textSize.Height)));

                case ContentAlignment.TopRight:
                    textLeft = Convert.ToInt32(clientRect.Width - textSize.Width);
                    return new Rectangle((clientRect.Left + textLeft), clientRect.Top, Convert.ToInt32(Math.Truncate(textSize.Width)), Convert.ToInt32(Math.Truncate(textSize.Height)));

                case ContentAlignment.MiddleLeft:
                    return new Rectangle(clientRect.Left, clientRect.Height / 2 - Convert.ToInt32(Math.Truncate(textSize.Height / 2)), Convert.ToInt32(Math.Truncate(textSize.Width)), Convert.ToInt32(Math.Truncate(textSize.Height)));

                case ContentAlignment.MiddleCenter:
                    textLeft = (clientRect.Width / 2) - (Convert.ToInt32(Math.Truncate(textSize.Width)) / 2);
                    return new Rectangle((clientRect.Left + textLeft), clientRect.Height / 2 - Convert.ToInt32(Math.Truncate(textSize.Height / 2)), Convert.ToInt32(Math.Truncate(textSize.Width)), Convert.ToInt32(Math.Truncate(textSize.Height)));

                case ContentAlignment.MiddleRight:
                    textLeft = Convert.ToInt32(clientRect.Width - textSize.Width);
                    return new Rectangle((clientRect.Left + textLeft), clientRect.Height / 2 - Convert.ToInt32(Math.Truncate(textSize.Height / 2)), Convert.ToInt32(Math.Truncate(textSize.Width)), Convert.ToInt32(Math.Truncate(textSize.Height)));

                case ContentAlignment.BottomLeft:
                    return new Rectangle(clientRect.Left, Convert.ToInt32(Math.Truncate(clientRect.Bottom - textSize.Height)), Convert.ToInt32(Math.Truncate(textSize.Width)), Convert.ToInt32(Math.Truncate(textSize.Height)));

                case ContentAlignment.BottomCenter:
                    textLeft = (clientRect.Width / 2) - (Convert.ToInt32(Math.Truncate(textSize.Width)) / 2);
                    return new Rectangle((clientRect.Left + textLeft), Convert.ToInt32(Math.Truncate(clientRect.Bottom - textSize.Height)), Convert.ToInt32(Math.Truncate(textSize.Width)), Convert.ToInt32(Math.Truncate(textSize.Height)));

                case ContentAlignment.BottomRight:
                    textLeft = Convert.ToInt32(clientRect.Width - textSize.Width);
                    return new Rectangle((clientRect.Left + textLeft), Convert.ToInt32(Math.Truncate(clientRect.Bottom - textSize.Height)), Convert.ToInt32(Math.Truncate(textSize.Width)), Convert.ToInt32(Math.Truncate(textSize.Height)));
            }
            return new Rectangle();
        }

        protected override void OnFontChanged(EventArgs e)
        {
            RaiseEvent();
        }

        protected override void OnForeColorChanged(EventArgs e)
        {
            RaiseEvent();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            e.Graphics.CompositingMode = CompositingMode.SourceOver;
            e.Graphics.CompositingQuality = CompositingQuality.GammaCorrected;
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

            DrawControlBorder(e.Graphics, ClientRectangle);
            DrawControlText(e.Graphics, ClientRectangle);
        }

        protected override void OnPaintBackground(PaintEventArgs pevent)
        {
            //- Nothing to do
        }

        protected override void OnTabIndexChanged(EventArgs e)
        {
            if (string.Compare(Text, 0, "TransparentLabel", 0, 7, true) == 0)
                Text = Name;
        }

        private void OnPropertyChanged(bool recreateHandle)
        {
            if (((Parent != null)))
            {
                //Dim _ControlRect As Rectangle = New Rectangle(Me.Location, Me.Size)
                //Me.Parent.Invalidate(_ControlRect, True)
            }
            if ((recreateHandle))
                RecreateHandle();
            Invalidate();
        }

        private void RaiseEvent()
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(true);
            }
        }
    }
}